import gradio as gr
import os
from openai import OpenAI
import json
import uvicorn
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Optional

# --- 配置部分 ---
# 从环境变量或直接设置您的百度AI API Key
BAIDU_API_KEY = os.environ.get("BAIDU_API_KEY", "xxx")  # 请替换为您的API Key
BAIDU_BASE_URL = "https://aistudio.baidu.com/llm/lmapi/v3"
MODEL_NAME = "ernie-4.5-turbo-vl"  # 使用百度模型

# 初始化OpenAI客户端以兼容百度API
client = OpenAI(
    api_key=BAIDU_API_KEY,
    base_url=BAIDU_BASE_URL,
)


# --- 核心处理函数 ---
def generate_investment_recommendations_core(
    investment_amount,
    risk_tolerance,
    investment_period,
    investment_goal,
    existing_investments="",
    financial_knowledge="",
):
    """
    根据用户输入生成投资建议的核心逻辑
    返回一个字典: {"success": bool, "result": str} 或 {"success": bool, "error": str}
    """
    # 构建发送给AI的指令(Prompt)
    prompt = f"""
    你是一位资深的投资顾问，拥有丰富的投资经验和专业知识。请根据以下信息，为这位投资者提供一份详细的个性化投资建议：

    投资者信息：
    - 可投资金额: {investment_amount}元
    - 风险承受能力: {risk_tolerance}
    - 投资期限: {investment_period}
    - 投资目标: {investment_goal}
    - 现有投资情况: {existing_investments if existing_investments else '未说明'}
    - 金融知识水平: {financial_knowledge if financial_knowledge else '未说明'}

    请结合你的专业知识，为该投资者生成一份个性化的投资分析报告。报告应包含以下内容：

    1. 投资状况分析：
       - 根据提供的信息，分析投资者的风险偏好和投资需求
       - 评估当前投资目标的合理性和可行性

    2. 资产配置建议：
       - 建议的资产配置比例（如股票、债券、现金、基金等）
       - 解释为何这样的配置适合该投资者
       - 不同市场环境下的调整建议

    3. 具体投资产品推荐：
       - 根据资产配置建议，推荐具体的投资产品类型或示例
       - 说明推荐理由（如风险收益特征、流动性等）
       - 提及需要避免的投资产品类型

    4. 投资策略与注意事项：
       - 适合该投资者的投资策略（如定投、价值投资等）
       - 风险提示和应对措施
       - 投资组合再平衡的建议
       - 其他需要注意的重要事项

    请确保你的回答专业、清晰、有条理，并以易于阅读的格式（如列表、加粗标题等）呈现。
    所有建议都应基于普遍适用的投资原则，不构成具体的投资操作指令。
    """

    try:
        # 调用百度AI API
        completion = client.chat.completions.create(
            model=MODEL_NAME,
            messages=[{"role": "user", "content": prompt}],
            stream=False,
            temperature=0.6,  # 适当调整创造性
        )

        # 获取AI回复内容
        ai_response = completion.choices[0].message.content
        return {"success": True, "result": ai_response}
    except Exception as e:
        # 错误处理
        print(f"调用AI API时出错: {e}")
        return {"success": False, "error": f"分析失败：{str(e)}"}


# --- 用于Gradio界面的包装函数 ---
def generate_investment_recommendations_for_gradio(
    investment_amount,
    risk_tolerance,
    investment_period,
    investment_goal,
    existing_investments="",
    financial_knowledge="",
):
    """包装函数，供Gradio界面调用，只返回字符串"""
    result_dict = generate_investment_recommendations_core(
        investment_amount,
        risk_tolerance,
        investment_period,
        investment_goal,
        existing_investments,
        financial_knowledge,
    )
    if result_dict["success"]:
        return result_dict["result"]
    else:
        return "抱歉，生成投资建议时遇到了问题，请稍后重试。"


# --- Gradio界面定义 ---
def gradio_interface():
    with gr.Blocks(title="AI投资顾问") as demo:
        gr.Markdown("# 💹 个性化投资模拟AI")
        gr.Markdown("输入您的投资信息，获取专业的个性化投资建议。")

        with gr.Row():
            with gr.Column(scale=1):
                investment_amount = gr.Number(
                    label="可投资金额 (元)", precision=0, minimum=1000, value=100000
                )
                risk_tolerance = gr.Radio(
                    label="风险承受能力",
                    choices=["保守型", "稳健型", "平衡型", "进取型", "激进型"],
                    value="平衡型",
                )
                investment_period = gr.Dropdown(
                    label="投资期限",
                    choices=[
                        "短期 (1年内)",
                        "中期 (1-3年)",
                        "中长期 (3-5年)",
                        "长期 (5年以上)",
                    ],
                    value="中长期 (3-5年)",
                )

            with gr.Column(scale=1):
                investment_goal = gr.Dropdown(
                    label="主要投资目标",
                    choices=[
                        "资产保值",
                        "稳健增值",
                        "子女教育储备",
                        "退休养老储备",
                        "购房首付积累",
                        "财富快速增长",
                        "其他目标",
                    ],
                    value="稳健增值",
                )
                financial_knowledge = gr.Radio(
                    label="金融知识水平",
                    choices=["入门级", "基础级", "进阶级", "专业级"],
                    value="基础级",
                )

        existing_investments = gr.Textbox(
            label="现有投资情况 (可选)", placeholder="例如：股票30%，基金40%，存款30%"
        )

        btn = gr.Button("🚀 生成投资建议", variant="primary")
        output = gr.Markdown(label="投资分析结果")

        btn.click(
            fn=generate_investment_recommendations_for_gradio,
            inputs=[
                investment_amount,
                risk_tolerance,
                investment_period,
                investment_goal,
                existing_investments,
                financial_knowledge,
            ],
            outputs=output,
        )

        gr.Markdown(
            """
        ---
        ## API 接入
        本应用提供API接口供前端调用：
        - **POST** `/api/generate`
        - **Body (JSON)**: 
          `{"investment_amount": int, "risk_tolerance": str, "investment_period": str, 
            "investment_goal": str, "existing_investments": str (可选), 
            "financial_knowledge": str (可选)}`
        - **Response (JSON)**: `{"success": bool, "result": str (AI回复)}` 或 `{"success": false, "error": str}`
        
        > 免责声明：所有建议仅供参考，不构成任何投资决策依据。投资有风险，入市需谨慎。
        """
        )

    return demo


# --- FastAPI应用和API端点定义 ---

# 创建FastAPI应用实例
app = FastAPI(
    title="个性化投资模拟AI服务", description="提供Gradio界面和API接口用于投资建议生成"
)


# 定义请求体模型
class InvestmentRequest(BaseModel):
    investment_amount: int
    risk_tolerance: str
    investment_period: str
    investment_goal: str
    existing_investments: Optional[str] = ""
    financial_knowledge: Optional[str] = ""


# 定义API端点
@app.post("/api/generate", summary="生成投资建议")
async def api_generate_recommendations(request: InvestmentRequest):
    """API端点：接收JSON请求，返回AI生成的投资建议"""
    result = generate_investment_recommendations_core(
        request.investment_amount,
        request.risk_tolerance,
        request.investment_period,
        request.investment_goal,
        request.existing_investments,
        request.financial_knowledge,
    )
    if result["success"]:
        return result
    else:
        raise HTTPException(status_code=500, detail=result["error"])


# 健康检查端点
@app.get("/health", summary="健康检查")
async def health_check():
    return {"status": "healthy"}


# 挂载Gradio界面
demo = gradio_interface()
app = gr.mount_gradio_app(app=app, blocks=demo, path="/")

if __name__ == "__main__":
    print("🚀 启动个性化投资模拟AI服务...")
    print("📱 Gradio界面访问地址: http://localhost:7860")
    print("💻 FastAPI文档地址: http://localhost:7860/docs")
    print("-" * 50)

    # 启动应用
    uvicorn.run(app, host="0.0.0.0", port=7860)
